home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-01
/
smailsrc.zip
/
UUPC.ZIP
/
DCP.C
< prev
next >
Wrap
Text File
|
1990-04-04
|
9KB
|
444 lines
/*
For best results in visual layout while viewing this file, set
tab stops to every 8 columns.
*/
/*
dcp.c
Revised edition of dcp
Stuart Lynne May/87
Copyright (c) Richard H. Lamb 1985, 1986, 1987
Changes Copyright (c) Stuart Lynne 1987
Maintenance Notes:
25Aug87 - Added a version number - Jal
25Aug87 - Return 0 if contact made with host, or 5 otherwise.
04Sep87 - Bug causing premature sysend() fixed. - Randall Jessup.
*/
/* "DCP" a uucp clone. Copyright Richard H. Lamb 1985,1986,1987 */
/*
This program implements a uucico type file transfer and remote
execution protocol.
Usage: uuio [-s sys] [-r] [-x debug]
e.g.
uuio [-x n] -r slave mode, wait for an incoming call.
uuio [-x n] -s HOST call the host "HOST".
uuio [-x n] -s all call all known hosts in the systems file.
uuio [-x n] -s any call any host we have work queued for.
uuio [-x n] same as the above.
*/
/*
* Modified 4/4/90 by Stephen Trier
* Now Supports smail/PC
*
* Removed internal rmail; added support for external rnews.
* Made -r flag a boolean, no argument required.
*/
#include "dcp.h"
#include "getopt.h"
#define VERSION "UUPC/uuio version 1.06"
int pktsize; /* packet size for this protocol*/
int remote; /* -1 means we're remote */
int msgtime; /* timout setting (length) */
int fp; /* current disk file handle */
FILE *fwork, *fsys, *syslog;
char workfile[80]; /* name of current workfile */
char *Rmtname = nil(char); /* system we want to call */
char rmtname[20]; /* system we end up talking to */
char s_systems[64]; /* full-name of systems file */
static char master(), slave(), receive(), send();
static int dcxqt();
static void cant(file)
char *file;
{
fprintf(stderr, "Can't open: \"%s\"\n", file);
exit(8);
} /*cant*/
int dcpmain(argc, argv)
int argc;
char *argv[];
{
int Contacted = FALSE;
int option;
debuglevel = 0;
remote = MASTER;
fp = -1;
fwork = nil(FILE);
while ((option = getopt(argc, argv, "rs:x:")) != EOF)
switch (option) {
case 'r':
remote = !remote;
break;
case 's':
Rmtname = strdup(optarg);
break;
case 'x':
debuglevel = atoi(optarg);
break;
case '?':
puts("\nUsage:\tuuio [-s sys] [-r] [-x debug]");
return 4;
}
if (optind != argc) {
puts("Extra parameter(s) at end.");
return 4;
}
if (Rmtname == nil(char))
Rmtname = "any";
if ((logfile = FOPEN(LOGFILE, "a", TEXT)) == nil(FILE))
cant(LOGFILE);
logecho = ((remote == MASTER) ? TRUE : FALSE);
/*
if ((syslog = FOPEN(SYSLOG, "a", TEXT)) == nil(FILE))
cant(SYSLOG);
*/
mkfilename(s_systems, confdir, SYSTEMS);
printmsg(0, "%s", VERSION);
if (remote == MASTER) {
char m_state = 'I';
printmsg(0, "calling \"%s\", debug=%d",
Rmtname, debuglevel);
if ((fsys = FOPEN(s_systems, "r", TEXT)) == nil(FILE))
exit(FAILED);
for ( ; ; ) {
printmsg(4, "M state = %c", m_state);
switch (m_state) {
case 'I':
m_state = getsystem();
break;
case 'S':
m_state = callup();
break;
case 'P':
m_state = startup();
break;
case 'D':
m_state = master();
Contacted = TRUE;
break;
case 'Y':
m_state = sysend();
break;
case 'G':
if (equal(Rmtname, "any"))
m_state = 'Y';
else
m_state = 'I';
break;
}
if (m_state == 'A')
break;
}
fclose(fsys);
}
else { /* slave mode */
char s_state = 'L';
if (openline(E_indevice, E_inspeed) == -1) {
printmsg(0, "can't open serial port");
return FALSE;
}
for ( ; ; ) {
printmsg(4, "S state = %c", s_state);
switch (s_state) {
case 'L':
s_state = login();
break;
case 'I':
s_state = startup();
break;
case 'R':
s_state = slave();
break;
case 'Y':
s_state = sysend();
break;
}
if (s_state == 'A')
break;
}
closeline();
}
/* scan and process any recieved X.* files */
printmsg(2, "calling dcxqt...");
if (dcxqt())
printmsg(0, "Error during dcxqt()!");
if (!Contacted)
printmsg(0, "\nCould not connect to remote system.");
fclose(logfile);
/*
fclose(syslog);
*/
return Contacted ? 0 : 5;
} /*dcpmain*/
/*
m a s t e r
*/
static char master()
{
char master_state = 'I';
for ( ; ; ) {
printmsg(4, "top level MASTER mode state = %c", master_state);
switch (master_state) {
case 'I':
master_state = sinit();
break;
case 'B':
master_state = scandir(rmtname);
break;
case 'S':
master_state = send();
break;
case 'Q':
master_state = sbreak();
break;
case 'G':
master_state = receive();
break;
case 'C':
master_state = 'Y';
break;
case 'Y':
master_state = endp();
break;
case 'P':
return 'Y';
case 'A':
return 'A';
default:
return 'A';
}
}
} /*master*/
/*
s l a v e
*/
static char slave()
{
char slave_state = 'I';
for ( ; ; ) {
printmsg(4, "top level SLAVE mode state = %c", slave_state);
switch (slave_state) {
case 'I':
slave_state = rinit();
break;
case 'F':
slave_state = receive();
break;
case 'C':
slave_state = schkdir();
break;
case 'T':
slave_state = 'B';
break;
case 'B':
slave_state = scandir(rmtname);
break;
case 'S':
slave_state = send();
break;
case 'Q':
slave_state = sbreak();
break;
case 'G':
return 'Y';
case 'Y':
slave_state = endp();
break;
case 'P':
return 'Y';
case 'A':
return 'A';
default:
return 'A';
}
}
} /*slave*/
/*
r e c e i v e
This is the state table switcher for receiving files.
*/
static char receive()
{
char receive_state = 'F'; /* Receive-Init is the start state */
for ( ; ; ) { /* Do until done */
printmsg(4, "receive state: %c", receive_state);
switch (receive_state) {
case 'F': /* Receive-File */
receive_state = rfile();
break;
case 'D': /* Receive-Data */
receive_state = rdata();
break;
case 'C': /* Complete state */
return 'C';
case 'A': /* "Abort" state */
return 'Y';
default:
return 'Y';
}
}
} /*receive*/
/*
s e n d
State table switcher for sending files
Loops until either it finishes, or an error is encountered.
Routines called by send() are responsible for changing the state.
*/
static char send()
{
char send_state = 'F'; /* Send initiate is the start state */
fp = -1; /* reset file getter/opener */
for ( ; ; ) { /* Do this as long as necessary */
printmsg(4, "send state: %c", send_state);
switch (send_state) {
case 'F':
send_state = sfile();
break; /* Send-File */
case 'D':
send_state = sdata();
break; /* Send-Data */
case 'Z':
send_state = seof();
break; /* Send-End-of-File */
case 'B':
return 'B'; /* Complete */
case 'A':
return 'Y'; /* "Abort" */
default:
return 'Y'; /* Unknown, fail */
}
}
} /*send*/
/*
d c x q t
A command formatter for DCP. RH Lamb
Sets up stdin and stdout on various machines.
There is NO command checking so watch what you send and who you let
to have access to your machine. "C rm /usr/*.*" could be executed!
*/
static int dcxqt()
{
char xfile[80];
while (xscandir(xfile) != nil(char)) {
char command[60], input[60], output[60], line[BUFSIZ];
char hostfile[132];
FILE *fxqt;
fxqt = FOPEN(xfile, "r", BINARY); /* inbound X.* file */
printmsg(2, "dcxqt: processing %s", xfile);
input[0] = output[0] = command[0] = '\0';
while (fgets(line, BUFSIZ, fxqt) != nil(char)) {
char *cp;
if ((cp = strchr(line, '\n')) != nil(char))
*cp = '\0';
printmsg(8, "dcxqt: %s", line);
switch (line[0]) {
case 'U':
break;
case 'I':
strcpy(input, &line[2]);
break;
case 'O':
strcpy(output, &line[2]);
break;
case 'C':
strcpy(command, &line[2]);
break;
case 'R':
break;
default :
break;
}
}
fclose(fxqt);
printmsg(0, "xqt: %s", command);
shell(command, input, output, nil(char));
unlink(xfile); /* already local name */
importpath(hostfile, input);
unlink(hostfile);
importpath(hostfile, output);
unlink(hostfile);
}
return FALSE;
} /*dcxqt*/